package com.gitee.cirnochat.group.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gitee.cirnochat.common.exception.BusinessException;
import com.gitee.cirnochat.common.model.enums.ErrorCode;
import com.gitee.cirnochat.group.mapper.GroupApplyMapper;
import com.gitee.cirnochat.group.model.entity.GroupApply;
import com.gitee.cirnochat.group.model.entity.GroupMember;
import com.gitee.cirnochat.group.model.enums.GroupApplyStatus;
import com.gitee.cirnochat.group.model.enums.GroupJoinType;
import com.gitee.cirnochat.group.model.vo.req.GroupApplyAddRequest;
import com.gitee.cirnochat.group.service.GroupApplyService;
import com.gitee.cirnochat.group.service.GroupMemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@RequiredArgsConstructor
public class GroupApplyServiceImpl extends ServiceImpl<GroupApplyMapper, GroupApply>
        implements GroupApplyService {

    private final GroupMemberService groupMemberService;

    // 发送加群申请
    @Override
    public void sendGroupApply(GroupApplyAddRequest req, Long fromId) {
        // 不能重复申请
        boolean exists = this.exists(new LambdaQueryWrapper<GroupApply>()
                .eq(GroupApply::getFromId, fromId)
                .eq(GroupApply::getGroupId, req.getGroupId())
                .eq(GroupApply::getStatus, GroupApplyStatus.PENDING));
        if (exists) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "你已发送过加群申请，请等待处理");
        }
        // 已是群成员
        boolean isMember = groupMemberService.lambdaQuery()
                .eq(GroupMember::getGroupId, req.getGroupId())
                .eq(GroupMember::getMemberId, fromId)
                .exists();
        if (isMember) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "你已在群中");
        }
        GroupApply apply = new GroupApply();
        apply.setFromId(fromId);
        apply.setGroupId(req.getGroupId());
        apply.setMessage(req.getMessage());
        apply.setStatus(GroupApplyStatus.PENDING);
        apply.setType(GroupJoinType.JOIN);
        this.save(apply);
    }

    // 管理员同意加群申请
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void acceptGroupApply(Long applyId, Long adminId) {
        GroupApply apply = this.getById(applyId);
        if (apply == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "申请不存在");
        }
        if (!GroupApplyStatus.PENDING.equals(apply.getStatus())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "申请已处理");
        }
        // 更新状态
        this.update(new LambdaUpdateWrapper<GroupApply>()
                .eq(GroupApply::getId, applyId)
                .set(GroupApply::getStatus, GroupApplyStatus.ACCEPTED));
        // 加入群成员
        GroupMember member = new GroupMember();
        member.setGroupId(apply.getGroupId());
        member.setMemberId(apply.getFromId());
        groupMemberService.save(member);
    }

    // 拒绝加群申请
    @Override
    public void rejectGroupApply(Long applyId, Long adminId) {
        GroupApply apply = this.getById(applyId);
        if (apply == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "申请不存在");
        }
        if (!GroupApplyStatus.PENDING.equals(apply.getStatus())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "申请已处理");
        }
        apply.setStatus(GroupApplyStatus.REJECTED);
        this.updateById(apply);
    }

    // 申请人撤回加群申请
    @Override
    public void revokeGroupApply(Long applyId, Long fromId) {
        GroupApply apply = this.getById(applyId);
        if (apply == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "申请不存在");
        }
        if (!apply.getFromId().equals(fromId)) {
            throw new BusinessException(ErrorCode.FORBIDDEN_ERROR, "无权限操作");
        }
        this.removeById(applyId);
    }

    // 查询某群的加群申请
    @Override
    public List<GroupApply> listGroupApplies(Long groupId) {
        return this.list(new LambdaQueryWrapper<GroupApply>()
                .eq(GroupApply::getGroupId, groupId)
                .orderByDesc(GroupApply::getCreateTime));
    }
}